package com.common.frame.mvp.base;

import android.content.Context;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;


import com.common.frame.bean.DiffBean;
import com.common.frame.bean.DiffHeadBean;
import com.common.frame.utils.ListUtils;
import com.common.frame.utils.SunDiffCallBack;

import java.util.ArrayList;
import java.util.List;


/**
 * BaseCustomVMAdapter
 */
public abstract class BaseCustomAdapter<T extends DiffBean> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<DiffBean> lists;
    private List<DiffHeadBean> mHeaders = new ArrayList<>();
    private SparseArray<DiffHeadBean> mHeaderArray = new SparseArray<>();
    private int BASE_ITEM_TYPE_HEADER = 100000;

    private SunDiffCallBack diffCallBack = new SunDiffCallBack();
    protected Context context;
    public DataEmptyListener dataEmptyListener;

    public BaseCustomAdapter(){}

    public BaseCustomAdapter(Context context){
        this.context = context;
    }


    public DiffHeadBean addHeaderView(View headerView) {
        if (headerView != null) {
            DiffHeadBean diffHeadBean = new DiffHeadBean(headerView);
            diffHeadBean.setAdapterType(BASE_ITEM_TYPE_HEADER++);
            mHeaders.add(diffHeadBean);
            mHeaderArray.put(diffHeadBean.getAdapterType(), diffHeadBean);

            List<DiffBean> newList = new ArrayList<>(mHeaders);
            if (lists != null){
                newList.addAll(lists);
            }
            diffUtils(lists, newList);
            return diffHeadBean;
        }
        return null;
    }

    public int getHeaderSize(){
        return mHeaders.size();
    }

    public boolean removeHeadView(View view){
        if (view != null){
            for (DiffHeadBean mHeader : mHeaders) {
                if (mHeader.view == view){
                    return removeHeaderView(mHeader);
                }
            }
        }
        return false;
    }

    public boolean removeHeaderView(DiffHeadBean headBean){
        if (headBean != null){
            boolean remove = mHeaders.remove(headBean);
            if (remove){
                mHeaders.remove(headBean.getAdapterType());
                List<DiffBean> newList = new ArrayList<>(mHeaders);
                if (lists != null){
                    newList.addAll(lists);
                }
                diffUtils(lists, newList);
            }
            return remove;
        }
        return false;
    }

    public void updateBean(int pos, DiffBean diffBean){
        lists.set(pos, diffBean);
        notifyItemChanged(pos);
    }

    public void delBean(int pos){
        lists.remove(pos);
        notifyItemRemoved(pos);
        if (ListUtils.isNull(lists)){
            if (dataEmptyListener != null) dataEmptyListener.onDataEmptyListener();
        }
    }

    public boolean isShowHeader() {
        return mHeaders.size() > 0;
    }



    public void setLists(List<T> newList) {
        List<DiffBean> diffList;
        if (newList == null){
            diffList = new ArrayList<>();
        }else{
            diffList = new ArrayList<>(newList);
        }
        if (isShowHeader()){
            diffList.addAll(0, mHeaders);
        }
        diffUtils(lists, diffList);
    }

    public void add(T t) {
        if (lists == null){
            lists = new ArrayList<>();
        }
        lists.add(t);
        notifyItemInserted(getItemCount()-1);
    }

    public void addFont(T t) {
        if (lists == null){
            lists = new ArrayList<>();
        }
        int pos = getHeaderSize();
        lists.add(pos, t);
        notifyItemInserted(pos-1);
    }

    public void addAll(List<T> newList) {
        if (ListUtils.isNotNull(newList)){
            List<DiffBean> diffList = new ArrayList<>(newList);
            if (lists != null) diffList.addAll(0, lists);
            diffUtils(lists, diffList);
        }
    }

    public List<DiffBean> getLists() {
        return lists;
    }

    public void diffUtils(List<DiffBean> oldList, List<DiffBean> newList){
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack.resetData(oldList, newList), true);
        lists = newList;
        diffResult.dispatchUpdatesTo(this);
    }

    @Override
    public int getItemCount() {
        return lists == null ? 0 : lists.size();
    }

    private boolean isHeader(int pos){
        return pos < mHeaders.size();
    }

    @Override
    public int getItemViewType(int position) {
        return getViewType(position);
    }

    public int getViewType(int position){
        return lists.get(position).getAdapterType();
    }

    public T getItem(int pos){
        return isHeader(pos) ? null : (T) lists.get(pos);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        if (mHeaderArray.indexOfKey(viewType) >= 0) {
            DiffHeadBean diffHeadBean = mHeaderArray.get(viewType);
            diffHeadBean.view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            return new RecyclerView.ViewHolder(diffHeadBean.view) {};
        }
        return createHolder(viewGroup, viewType);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        if (isHeader(position)){

        }else{
            bindViewHolder(position, viewHolder);
        }
    }

    protected abstract RecyclerView.ViewHolder createHolder(ViewGroup viewGroup, int viewType);

    protected abstract void bindViewHolder(int position, RecyclerView.ViewHolder viewHolder);

    public interface DataEmptyListener{
        void onDataEmptyListener();

    }

}